#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"
#include <math.h>
#include "testHelper.c"

#define NOISY_TEST 1

int checkSalvager(int testCardPos, struct gameState *testState, int choice1) {
  int functionError, choiceValue;
  struct gameState controlState;
  
  choiceValue = getCost(testState->hand[whoseTurn(testState)][choice1]);
  memcpy (&controlState, testState, sizeof(struct gameState));

  functionError = salvagerCard (testState, whoseTurn(testState), choice1, testCardPos);

  /* SIMULATE THE CARD EFFECT */
  controlState.numBuys++;
  if(choice1){
    controlState.coins = controlState.coins + choiceValue;
    discardCard(choice1, whoseTurn(&controlState), &controlState, 1);
  }
  discardCard(testCardPos, whoseTurn(&controlState), &controlState, 0);
  
  assert(functionError == 0); //no error playing the card
  
  //test to see if both the states are the same
  if(memcmp(&controlState, testState, sizeof(struct gameState)) == 0){
    return 0;
  }
  else{
    gameStateDiff(&controlState, testState);
    return 1;
  }
}

int main () {

  int i, n, numPlayers, currentPlayer, seed, testCardPos, success, failure, choice;

  int k[10] = {adventurer, council_room, feast, gardens, mine,
	       salvager, smithy, village, baron, great_hall};

  struct gameState G;
  
  printf ("***TESTING SALVAGER***\n");

  success = 0;
  failure = 0;
  PutSeed(floor(Random() * MODULUS));

  for (n = 0; n < 2000; n++) {
    /* Fill the Game State with garbage */
    for (i = 0; i < sizeof(struct gameState); i++) {
      ((char*)&G)[i] = floor(Random() * 256);
    }
    //initialize new game
    numPlayers = floor(Random() * PLAYER_RANGE) + 2;
    seed = floor(Random() * 1000);
    initializeGame(numPlayers, k, seed, &G);
    
    for (i = 0; i < numPlayers; i++){
      G.deckCount[i] = floor(Random() * MAX_DECK) + 5; //enough cards to draw from
      G.discardCount[i] = floor(Random() * MAX_DECK);
      G.handCount[i] = floor(Random() * MAX_HAND);
    }
    currentPlayer = floor(Random() * numPlayers); //define a current random player
    G.whoseTurn = currentPlayer; //set the game's current player to selected player
    testCardPos = floor(Random() * G.handCount[currentPlayer]); //define a random card in the current player's hand to test
    G.hand[currentPlayer][testCardPos] = salvager; //set that card to a salvager

    /* if choice is a multiple of 10, set to 0 so that we fall through
       the assertion in the function appx 10% of the time */
    choice = floor(Random() * G.handCount[currentPlayer]);
    if(choice % 10 == 0){
      choice = 0;
    }

    if(checkSalvager(testCardPos, &G, choice) == 0){
      success++;
    }
    else{
      failure++;
    }
  }

  printf ("\n***TESTS COMPLETE***\n***SUMMARY\n***Successful Tests: %d\n***Failed Tests: %d\n\n", success, failure); 

  return 0;
}
